package com.lvy.hczn.front.business.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.corundumstudio.socketio.SocketIOServer;
import com.lvy.hczn.front.business.common.Constants;
import com.lvy.hczn.front.system.domain.business.WcsResponse;
import com.lvy.hczn.front.business.dto.Param;
import com.lvy.hczn.front.business.dto.SearchCondition;
import com.lvy.hczn.front.business.service.UpOrDownPolicyService;
import com.lvy.hczn.front.business.service.WcsService;
import com.lvy.hczn.front.business.util.ResultUtil;
import com.lvy.hczn.front.common.core.redis.RedisCache;
import com.lvy.hczn.front.common.exception.UtilException;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RequestMapping("/wcs/")
@RestController
@Slf4j
public class WcsController {

    @Autowired
    private WcsService wcsService;

    @Autowired
    private SocketIOServer socketIOServer;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private UpOrDownPolicyService upOrDownPolicyService;

    @ApiOperation(value = "消息发送", notes = "消息发送")
    @GetMapping("testInfo")
    public void testInfo() {
        try {
            redisCache.setListOfRight("test:list:10", "a");
            redisCache.setListOfRight("test:list:10", "b");
            redisCache.setListOfLeft("test:list:10", "c");
            /*Thread.sleep(6000);
            UpOrDownPolicy upOrDownPolicy =  upOrDownPolicyService.getById("1527201964622041089");
            UUID uuid = (UUID) redisCache.get(CacheConstants.REDIS_KEY_SOCKET_CLIENT + ":" + upOrDownPolicy.getClientId());
            SocketIOClient socketIOClient = socketIOServer.getClient(uuid);
            socketIOClient.sendEvent("testInfo", JSONUtil.toJsonStr(upOrDownPolicy));
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @ApiOperation(value = "消息发送", notes = "消息发送")
    @GetMapping("testInfos")
    public void testInfos() {
        try {
            List<Object> list = redisCache.getList("test:list:10", 0, 0);
            String str = "";
            if (!list.isEmpty()) {
                str = list.get(0).toString();
            }
//            MessageInfo messageInfo = JSONUtil.toBean(JSONUtil.toJsonStr(list.get(0)),MessageInfo.class);
            redisCache.delListLeftPop("test:list:10");
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + str);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @ApiOperation(value = "消息发送", notes = "消息发送")
    @PostMapping("send")
    public ResultUtil sendMessage(@Valid @RequestBody Param param) {
        try {
            //todo 客户取货，原材料入库，请求分拣，分为不同方法，这样可以避免前端传流程，防止修改
            if (param.getMap() == null || param.getMap() == null) {
                return ResultUtil.failed("参数为空!");
            }
            wcsService.sendMessage(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 分拣原料入库
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "分拣原料入库", notes = "分拣原料入库")
    @PostMapping("sortingEntry")
    public ResultUtil sortingEntry(@RequestBody Param param) {
        try {
            //wcs一流程多topic响应，会提前展示按钮
            synchronized (this) {
                log.error("分拣原料入库参数：{}", JSONUtil.toJsonStr(param));
                wcsService.sortingEntry(param, param.getUpOrDownPolicy());
            }
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("sortingEntry: ｛｝", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    @ApiOperation(value = "分拣订单入库", notes = "分拣订单入库")
    @PostMapping("sortingOrderEntry")
    public ResultUtil sortingOrderEntry(@Valid @RequestBody Param param) {
        try {
            log.error("分拣订单入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.sortingOrderEntry(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("sortingOrderEntry: {}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 请求分拣出库
     * <p>
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "请求分拣出库", notes = "请求分拣出库")
    @PostMapping("sortingOut")
    public ResultUtil sortingOut(@Valid @RequestBody Param param) {
        try {
            log.error("请求分拣出库参数：" + JSONUtil.toJsonStr(param));
            wcsService.sortingOut(param);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("sortingOut:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 连续发指令到wcs,即一个指令响应成功后发送第二个指令，wcs暂时不支持一次性发全部指令
     * <p>
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "连续发指令到wcs", notes = "请求分拣出库")
    @PostMapping("sortingOutBatch")
    public ResultUtil sortingOutBatch(@RequestBody Param param) {
        try {
            log.error("连续发指令到wcs：" + JSONUtil.toJsonStr(param));
            wcsService.sortingOutBatch(param, false);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("sortingOutBatch:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 空箱入库
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "空箱入库", notes = "空箱入库")
    @PostMapping("emptyEntry")
    public ResultUtil emptyEntry(@Valid @RequestBody Param param) {
        try {
            log.error("空箱入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.emptyEntry(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("emptyEntry:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 合箱空箱入库
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "合箱空箱入库", notes = "合箱空箱入库")
    @PostMapping("emptyEntryOfMerge")
    public ResultUtil emptyEntryOfMerge(@Valid @RequestBody Param param) {
        try {
            log.error("合箱空箱入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.emptyEntryOfMerge(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("emptyEntryOfMerge:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 合箱原料入库
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "合箱原料入库", notes = "合箱原料入库")
    @PostMapping("mergeEntry")
    public ResultUtil mergeEntry(@RequestBody Param param) {
        try {
            log.error("合箱原料入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.mergeEntry(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("mergeEntry:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 采购入库
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "采购入库", notes = "采购入库")
    @PostMapping("purchaseEntry")
    public ResultUtil purchaseEntry(@Valid @RequestBody Param param) {
        try {
            log.error("采购入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.productEntry(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("purchaseEntry:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                log.error("purchaseEntry:{}", e);
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 强制入库,入货箱重量与称重不匹配
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "强制入库", notes = "强制入库")
    @PostMapping("entryForce")
    public ResultUtil entryForce(@Valid @RequestBody Param param) {
        try {
            log.error("强制入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.entryForceInfo(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("entryForce:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "wms原材料入库二次扫码", notes = "wms原材料入库二次扫码")
    @PostMapping("scan")
    public ResultUtil stockInBySecondScan(@Valid @RequestBody Param param) {
        try {
            WcsResponse response = JSONUtil.toBean(JSONUtil.toJsonStr(param.getMap()), WcsResponse.class);
            param.getUpOrDownPolicy().setProcessState(Constants.STATE_TO_WCS_TEN);
            wcsService.stockInBySecondScan(response, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("scan:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 非空箱出库不入库，wcs指定，指定指定货箱
     * <p>
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "非空箱出库不入库", notes = "非空箱出库不入库")
    @PostMapping("notEntryByBoxCode")
    public ResultUtil notEntryByBoxCode(@Valid @RequestBody Param param) {
        try {
            log.error("非空箱出库不入库参数：" + JSONUtil.toJsonStr(param));
            if (StrUtil.isEmpty(param.getUpOrDownPolicy().getBoxCode())) {
                return ResultUtil.failed("货箱编码为空");
            }
            param.getGoodsBox().setBoxCode(param.getUpOrDownPolicy().getBoxCode());
            //指定货箱编号出库，wcs默认是走的非空箱出库流程，web决定type值,暂时以出库单的outbound_order_type 4设为默认
            //即：空箱指定货箱编号出库，也是走的此方法
            wcsService.notEntry(param, Constants.OUTBOUND_TYPE_TWO, Constants.OUTBOUND_ORDER_TYPE_FOUR);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("notEntryByBoxCode:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 空箱出库不入库
     * <p>
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "空箱出库不入库", notes = "空箱出库不入库")
    @PostMapping("notEntryEmptyBox")
    public ResultUtil notEntryEmptyBox(@Valid @RequestBody Param param) {
        try {
            log.error("空箱出库不入库参数：" + JSONUtil.toJsonStr(param));
            //空箱出库区分：1、指定温区指定货箱编号出库；2、指定温区，指定数量出库
            wcsService.notEntry(param, Constants.OUTBOUND_TYPE_ONE, Constants.OUTBOUND_ORDER_TYPE_THREE);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("notEntryEmptyBox:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 采购空箱出库且入库
     * <p>
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "采购空箱出库且入库", notes = "采购空箱出库且入库")
    @PostMapping("purchaseEmptyDown")
    public ResultUtil purchaseEmptyDown(@Valid @RequestBody Param param) {
        try {
            synchronized (this) {
                log.error("采购空箱出库且入库参数：" + JSONUtil.toJsonStr(param));
                //空箱出库区分：1、指定温区指定货箱编号出库；2、指定温区，指定数量出库
                wcsService.purchaseEmptyDown(param, Constants.OUTBOUND_TYPE_ONE, Constants.OUTBOUND_ORDER_TYPE_THREE);
            }
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("purchaseEmptyDown:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }


    /**
     * 货箱净重称重
     *
     * @param param
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-04-07 20:20:51
     */
    @ApiOperation(value = "货箱净重称重", notes = "货箱净重称重")
    @PostMapping("netWeight")
    public ResultUtil netWeight(@RequestBody Param param) {
        try {
            log.error("货箱净重称重参数：" + JSONUtil.toJsonStr(param));
            wcsService.netWeightInit(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("netWeight:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 分拣中称重
     *
     * @param param
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-04-07 20:20:51
     */
    @ApiOperation(value = "分拣中称重", notes = "分拣中称重")
    @PostMapping("sortingWeight")
    public ResultUtil sortingWeight(@RequestBody Param param) {
        try {
            log.error("分拣中称重参数：" + JSONUtil.toJsonStr(param));
            return wcsService.sortingWeightInfo(param, param.getUpOrDownPolicy());
        } catch (Exception e) {
            log.error("sortingWeight:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 采购入库称重
     *
     * @param param
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-04-07 20:20:51
     */
    @ApiOperation(value = "采购入库称重", notes = "采购入库称重")
    @PostMapping("entryWeight")
    public ResultUtil entryWeight(@RequestBody Param param) {
        try {
            log.error("采购入库称重参数：" + JSONUtil.toJsonStr(param));
            wcsService.entryWeight(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("entryWeight:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * wcs返回状态到前端或者浏览器重新打开进入对应页面，则调此方法获取wcs返回信息
     * 注：wcs响应返回页面会有两次容错，一次是，浏览器误关，重新进入页面，从这取，
     * 二是误入页面，confirm提示是否继续
     * 三,confirm选否，且退出，需测试看什么情况，再处理
     *
     * @param searchCondition
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-05-20 17:22:35
     */
    @ApiOperation(value = "获取wcs响应信息", notes = "获取wcs响应信息")
    @PostMapping("selectResponseFromWcs")
    public ResultUtil selectResponseFromWcs(@RequestBody SearchCondition searchCondition) {
        try {
            return ResultUtil.ok(wcsService.selectResponseFromWcs(searchCondition.getType(), searchCondition.getClientId(), searchCondition.getProcessType()));
        } catch (Exception e) {
            log.error("selectResponseFromWcs:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 删除wcs响应信息
     * 注：
     * 没有直接查到就删除，而是由操作人员决定是否删除，是防止误进入页面
     *
     * @return com.lvy.hczn.common.core.util.ResultUtil
     * @author yw
     * @date 2022-05-20 17:22:35
     */
    @ApiOperation(value = "删除wcs响应信息", notes = "删除wcs响应信息")
    @PostMapping("delResponseFromWcs")
    public ResultUtil delResponseFromWcs(@RequestBody SearchCondition searchCondition) {
        try {
            log.error("wcs响应删除：{}", JSON.toJSONString(searchCondition));
            redisCache.delListLeftPop(searchCondition.getType() + Constants.TYPE_WCS_RESPONSE + searchCondition.getClientId());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("delResponseFromWcs:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 销售退货入库
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "销售退货入库", notes = "销售退货入库")
    @PostMapping("returnEntry")
    public ResultUtil returnEntry(@RequestBody Param param) {
        try {
            log.error("销售退货入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.returnEntry(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("mergeEntry:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 临期报损入库
     * 不同的入库展开不同的方法，流程写在服务端，不写在web端
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "临期报损入库", notes = "临期报损入库")
    @PostMapping("frmLossEntry")
    public ResultUtil frmLossEntry(@RequestBody Param param) {
        try {
            log.error("临期报损入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.frmLossEntry(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("mergeEntry:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }
}
